# -*- coding: UTF-8 -*-
# Author: Damon(wuud1)
# CreateDate: 2018-07-25
# Message: 可以将两个数据库表合并为一个,从a表读取数据,写入b表.前提两个表的字段是相同的,这个脚本遇到的困难是python2对于中文的不友好
# 读取到的数据如果包含中文的话,插入b表时会报错,把中文encode为utf8会导致插入b表的是/x2a/x2b等数据,最终解决用了%s替代符,困难在于自动
# 判断表中有多少字段及最终sql语句的拼装上.本脚本应用场景: a和b表字段相同,id却冲突,没办法通过sequel pro 粘贴复制过去,可以通过运行
# 此脚本,轻松随意.例如代码测试阶段,怕出错不想把数据直接插入到最终表里,先插入在测试表中,代码无误,数据全都插入测试表,此时两个表id冲突,
# 又不想再重新跑一遍程序,就可以用本脚本
import sys
import pymysql

reload(sys)
sys.setdefaultencoding('utf-8')

class Table_MoreToOne(object):

    def __init__(self, *args, **kwargs):

        self.src_dbconfig = kwargs.get("src_config")  # 数据源数据库配置
        self.dest_dbconfig = kwargs.get("dest_config")  # 目标数据库配置
        self.src_table = kwargs.get("src_table")  # 数据源表
        self.dest_table = kwargs.get("dest_table")  # 目标表
        self.num = 0  # 计数变量

    def get_conn(self, dbconfig_dict):
        conn = pymysql.connect(**dbconfig_dict)
        return conn

    def get_cursor(self, conn, type='stream'):
        if type == 'stream':
            return conn.cursor(pymysql.cursors.SSCursor)  # 返回流式游标,查询大量数据时不占用内存(返回数据形式是元组)
        elif type == 'dict':
            return conn.cursor(pymysql.cursors.DictCursor)  # 返回字典形式游标,查询出的数据以字典形式返回
        else:
            raise Exception("cursor type error")

    def run(self):
        src_conn = self.get_conn(self.src_dbconfig)
        dest_conn = self.get_conn(self.dest_dbconfig)
        src_curs = self.get_cursor(src_conn)
        dest_curs = self.get_cursor(dest_conn)

        select_sql = '''select * from {}'''.format(self.src_table)  # 读取数据的sql语句
        src_curs.execute(select_sql)
        for data in src_curs:
            insert_sql = '''INSERT INTO `{}` VALUES ('''.format(self.dest_table)
            data_list = list(data)  # 把元组转为列表
            data_list[0] = 0  # id换为0来占位, 因为两个表的id可能冲突
            data_tuple = tuple(data_list)  # 再转为元组

            # 处理sql语句编码问题,拼装最后的sql语句
            sql_tail = ''
            for i in data_tuple:
                j = '%d,'
                if type(i) is unicode:
                    j = "'%s',"
                if data_tuple.index(i) == len(data_tuple)-1:
                    j = "'%s'"
                sql_tail += j
            # print sql_tail
            insert_sql = '''{}{})'''.format(insert_sql, sql_tail)
            insert_sql = insert_sql % data_tuple
            # print insert_sql
            ####
            # 此处可以写过滤条件
            ####

            try:
                dest_curs.execute(insert_sql)
                self.num += 1
            except Exception as e:
                print(insert_sql)
                raise e

            if self.num % 100 == 0:  # 每一百条提交一次
                dest_conn.commit()
                print("insert {} commit, current_num:{}".format(self.dest_table, self.num))
        dest_conn.commit()
        print("insert success!!!, total_num:{}".format(self.num))


        src_curs.close()
        dest_curs.close()
        src_conn.close()
        dest_conn.close()



if __name__ == '__main__':
    src_config = dict(  # 数据源数据库配置
        host="127.0.0.1",
        port=3306,
        user="root",
        passwd="123456",
        db="my_data",
        charset="utf8",
        )
    dest_config = dict(  # 目标数据库配置
        host="127.0.0.1",
        port=3306,
        user="root",
        passwd="123456",
        db="my_data",
        charset="utf8",
        )
    src_table = '0719_pid'  # 读取表
    dest_table = '0716_pid'  # 插入表
    tools = Table_MoreToOne(src_config=src_config, dest_config=dest_config, src_table=src_table, dest_table=dest_table)
    tools.run()